package com.acme.bankapp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.IClient;
import com.acme.bankapp.domain.bank.accounts.Account;
import com.acme.bankapp.domain.bank.exceptions.NotEnoughFundsException;
import com.acme.bankapp.service.app.BankService;
import com.acme.bankapp.service.app.EventDispatcher;
import com.acme.bankapp.service.feed.FeedService;

public class BankApplication {
	public static void main(String[] args) {
		Bank b = new Bank();
		if (args.length > 0) {
			try {
				if (args[0].endsWith("-loadfeed")) {
					FeedService.readClientsFromFeed(
						new BankService(b, new EventDispatcher(),
								new ThreadPoolExecutor(10, 16, 1, TimeUnit.HOURS,
										new ArrayBlockingQueue<Runnable>(100500))),
										new File(args[1])); 
				} else {
					new BankService(new Bank().loadBank(new File(args[0])),
						new EventDispatcher(),
								new ThreadPoolExecutor(10, 16, 1, TimeUnit.HOURS,
										new ArrayBlockingQueue<Runnable>(100500)));
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void modifyBank(Bank bank, double amount) {
		for (IClient c : bank.getClients()) {
			for (Account a : c.getAccounts()) {
				if (amount < 0) {
					try {
						a.withdraw(-amount);
					} catch (NotEnoughFundsException e) {
						e.printStackTrace();
					}
				} else {
					a.deposit(amount);
				}
			}
		}
	}
	
	public static void printBalance(Bank bank) {
		for (IClient c : bank.getClients()) {
			System.out.println(c.toString());
		}
	}
	
	public static void printMaximumAmountToWithdraw(Bank bank) {
		for (IClient c : bank.getClients()) {
			Collection<Account> accs = c.getAccounts();
			double[] sums = new double[accs.size()];
			int idx = 0;
			for (Account acc : accs) {
				sums[idx++] = acc.getBalance();
			}
			System.out.println(String.format("%1: %2", c.getClientSalutation(), sums));
		}
	}

}